// Legal Notices:
//    Copyright (C) 2011 - 2012, GuruCE.
//    http://guruce.com
//    ALL RIGHTS RESERVED
//
//    This file, software, or program is supplied under the terms of a
//    license agreement and/or nondisclosure agreement with GuruCE
//    and may not be copied or disclosed except in accordance with the 
//    terms of that agreement.  This file, software, or program contains 
//    copyrighted material and/or trade secret information of 
//    GuruCE, and must be treated as such. GuruCE reserves all rights in
//    this material, except as the license agreement or nondisclosure 
//    agreement specifically indicate.
//
//    All rights reserved.  No part of this program or publication may be
//    reproduced, transmitted, transcribed, stored in a retrieval system
//    retrieval system, or translated into any language or computer
//    language, in any form or by any means, electronic, mechanical,
//    magnetic, optical, chemical, manual, or otherwise, without the prior
//    written permission of GuruCE.
//
// Disclaimer:
//    GuruCE makes no warranty of any kind regarding this code.  This code
//    is provided on an "AS-IS" basis and GuruCE will not provide any 
//    support assistance, installation, training or other services.
//    GuruCE does not provide any updates, enhancements or extensions. 
//    GuruCE specifically disclaims any warranty of merchantability, 
//    non-infringement, fitness for any particular purpose, or any other 
//    warranty.
//
//    GuruCE disclaims all liability, including liability for infringement
//    of any proprietary rights, relating to use of the code. No license, 
//    express or implied, by estoppel or otherwise, to any intellectual 
//    property rights is granted herein.
//
//    GuruCE has no responsibility under warranty, indemnification or 
//    otherwise, for the modification or customization of any GuruCE
//    software by GuruCE, customer, website user or any third party even
//    if such customization and/or modification is done using GuruCE
//    tools, training or methods documented by GuruCE.
//
#pragma once

#include "flexcandefs.h"

extern "C"
{
    //-------------
    // FlexCANInit
    //-------------
    // Must be called before anything else.
    //
    // Input:
    //      dwIndex         - CAN instance index (1-based)
    // Return: 
    //      FALSE on error (GetLastError() will return error code)
    BOOL FlexCANInit(DWORD dwIndex);

    //---------------
    // FlexCANDeinit
    //---------------
    // Must be called when the FlexCAN is no longer needed (cleans up handles etc).
    //
    // Input:
    //      dwIndex         - CAN instance index (1-based)
    // Return: 
    //      FALSE on error (GetLastError() will return error code)
    BOOL FlexCANDeinit(DWORD dwIndex);

    //-----------------
    // FlexCANTransfer
    //-----------------
    // Transfer multiple packets (either read or write).
    //
    // Input:
    //      dwIndex         - CAN instance index (1-based)
    //      pTransferBlock  - Pointer to CAN_TRANSFER_BLOCK structure containing
    //                        an array of CAN_PACKETs:
    //          CAN_PACKET.btIndex      - CAN Bus Message Buffer Index to use for this transmission. Set to 0xFF to let driver find a free message buffer
    //          CAN_PACKET.bWrite       - This transmission is read (CAN_READ) or write (CAN_WRITE)
    //          CAN_PACKET.canFrame     - The actual frame data. See FlexCANWriteFrame for a description of the CAN_FRAME items
    //          CAN_PACKET.bTxOnRemoteRx- CAN_TXNOW to send immediately, CAN_TXONREMOTERX to send when a frame with the same ID is received. Only valid when (CAN_WRITE && CAN_DATA)
    //          CAN_PACKET.btPriority   - The transmission priority (0 = highest priority, 7 = lowest priority)
    //          CAN_PACKET.dwIDMask     - Bitmask for ID (when CAN_READ or CAN_REMOTE or CAN_TXONREMOTERX): 0; don't care, 1; the corresponding bit in the ID is checked against the one received
    //          CAN_PACKET.dwTimeout    - Maximum time this transmission can take in ms
    //          CAN_PACKET.dwError      - Receives the result of the action on this packet (ERROR_SUCCESS == All ok)
    // Output:
    //          CAN_PACKET.canFrame     - See FlexCANWriteFrame for a description of the output when CAN_WRITE and see FlexCANReadFrame for a description of the output when CAN_READ
    // Return: 
    //      FALSE on error (GetLastError() will return error code)
    //      The dwError item of each CAN_PACKET will contain the transfer result per packet (see FlexCANWriteFrame for a list of possible errors)
    BOOL FlexCANTransfer(DWORD dwIndex, PCAN_TRANSFER_BLOCK pTransferBlock);

    //-------------------
    // FlexCANWriteFrame
    //-------------------
    // Write a single frame over the CAN bus.
    //
    // Input:
    //      dwIndex         - CAN instance index (1-based)
    //      bTxOnRemoteRx   - CAN_TXNOW to send immediately, CAN_TXONREMOTERX to send when a frame with the same ID is received
    //      btPriority      - Priority to use for transmitting this frame (0 = highest priority, 7 = lowest priority)
    //      pCanFrame       - Pointer to a CAN_FRAME:
    //          CAN_FRAME.bExtended     - Frame format is standard (CAN_STANDARD) or extended (CAN_EXTENDED)
    //          CAN_FRAME.bRemote       - CAN_DATA to send a date frame, CAN_REMOTE to request a remote frame
    //          CAN_FRAME.dwID          - Message ID. If using standard frame format the ID is 11 bits, if using the extended format the ID is 29 bits
    //          CAN_FRAME.btDataLen     - Number of valid bytes in btData
    //          CAN_FRAME.btData[0..8]  - Message data, max 8 bytes
    //      dwTimeout       - Maximum time this transmission can take in ms
    //      dwIDMask        - Bitmask for ID (when CAN_REMOTE or CAN_TXONREMOTERX): 0; don't care, 1; the corresponding bit in the ID is checked against the one received
    // Output:
    //          CAN_FRAME.wTimestamp - Receives the transmission timestamp (captured when the frame first appeared on the bus)
    //      if CAN_REMOTE:
    //          CAN_FRAME.bExtended     - Frame format is standard (CAN_STANDARD) or extended (CAN_EXTENDED)
    //          CAN_FRAME.bRemote       - Received frame is a data frame (CAN_DATA) or a remote frame (CAN_REMOTE)
    //          CAN_FRAME.dwID          - Message ID. If standard frame format the ID is 11 bits, if using the extended format the ID is 29 bits
    //          CAN_FRAME.wTimestamp    - Receives the transmission timestamp (captured when the frame first appeared on the bus)
    //          CAN_FRAME.wDataLen      - Number of valid bytes in btData
    //          CAN_FRAME.btData[0..8]  - Message data, max 8 bytes
    // Return: 
    //      ERROR_SUCCESS           - Successful
    //      ERROR_INVALID_PARAMETER - Parameter error
    //      ERROR_INVALID_DATA      - Received packet (when CAN_FRAME.bRemote == CAN_REMOTE) contained invalid data
    //      ERROR_TIMEOUT           - Timeout while sending (or receiving when CAN_FRAME.bRemote == CAN_REMOTE)
    DWORD FlexCANWriteFrame(DWORD dwIndex, BOOL bTxOnRemoteRx, BYTE btPriority, PCAN_FRAME pCanFrame, DWORD dwTimeout, DWORD dwIDMask=0);

    //------------------
    // FlexCANReadFrame
    //------------------
    // Read a single frame from the CAN bus.
    //
    // Input:
    //      dwIndex         - CAN instance index (1-based)
    //      pCanFrame       - Pointer to a CAN_FRAME:
    //          CAN_FRAME.bExtended     - Frame format is standard (CAN_STANDARD) or extended (CAN_EXTENDED)
    //          CAN_FRAME.dwID          - Message ID. If using standard frame format the ID is 11 bits, if using the extended format the ID is 29 bits
    //      dwTimeout       - Maximum time this transmission can take in ms
    //      dwIDMask        - Bitmask for ID: 0; don't care, 1; the corresponding bit in the ID is checked against the one received
    // Output:
    //          CAN_FRAME.bExtended     - Frame format is standard (CAN_STANDARD) or extended (CAN_EXTENDED)
    //          CAN_FRAME.bRemote       - Received frame is a data frame (CAN_DATA) or a remote frame (CAN_REMOTE)
    //          CAN_FRAME.dwID          - Message ID. If standard frame format the ID is 11 bits, if using the extended format the ID is 29 bits
    //          CAN_FRAME.wTimestamp    - Receives the transmission timestamp (captured when the frame first appeared on the bus)
    //          CAN_FRAME.wDataLen      - Number of valid bytes in btData
    //          CAN_FRAME.btData[0..8]  - Message data, max 8 bytes
    // Return: 
    //      ERROR_SUCCESS           - Successful
    //      ERROR_INVALID_PARAMETER - Parameter error
    //      ERROR_INVALID_DATA      - Received packet (when CAN_FRAME.bRemote == CAN_REMOTE) contained invalid data
    //      ERROR_TIMEOUT           - Timeout while sending (or receiving when CAN_FRAME.bRemote == CAN_REMOTE)
    DWORD FlexCANReadFrame(DWORD dwIndex, PCAN_FRAME pCanFrame, DWORD dwTimeout, DWORD dwIDMask);

    //-------------------
    // FlexCANSetBitrate
    //-------------------
    // Set the FlexCAN bus bitrate.
    //
    // Input:
    //      dwIndex         - CAN instance index (1-based)
    //      pdwBitrate      - Pointer to a DWORD containing the requested bitrate (in bps)
    // Output:
    //      pdwBitrate      - Contains the actual bitrate set (this can differ due to prescaler roundings)
    // Return: 
    //      FALSE on error (GetLastError() will return error code)
    BOOL FlexCANSetBitrate(DWORD dwIndex, LPDWORD pdwBitrate);

    //-------------------
    // FlexCANGetBitrate
    //-------------------
    // Get the FlexCAN bus bitrate.
    //
    // Input:
    //      dwIndex         - CAN instance index (1-based)
    //      pdwBitrate      - Pointer to a DWORD
    // Output:
    //      pdwBitrate      - Contains the current bitrate
    // Return: 
    //      FALSE on error (GetLastError() will return error code)
    BOOL FlexCANGetBitrate(DWORD dwIndex, LPDWORD pdwBitrate);
}